<script setup lang="ts">
import { ref, onMounted, watch, onUnmounted, nextTick } from 'vue'
import * as echarts from 'echarts'
import type { EChartsOption } from 'echarts';
import type { TitleOption, XAXisOption, YAXisOption } from 'echarts/types/dist/shared';
import 'echarts/lib/chart/sankey';

const occupations = [
  '全部',
  '专业技术人员',
  '国家机关工作人员',
  '企业管理人员',
  '商业服务业人员',
  '农林牧渔人员',
  '生产运输人员',
  '军人',
  '其他人员'
]

const occupationSubcategories = {
  '专业技术人员': ['软件工程师', '医生', '教师', '会计师', '建筑师'],
  '国家机关工作人员': ['行政办公人员', '政策研究员', '公务员', '事业单位职员', '机关工作人员'],
  '企业管理人员': ['总经理', '人力资源经理', '财务总监', '运营总监', '项目经理'],
  '商业服务业人员': ['销售代表', '客户服务', '理财顾问', '房地产经纪人', '保险代理'],
  '农林牧渔人员': ['农艺师', '畜牧师', '园艺师', '渔业技术员', '林业工程师'],
  '生产运输人员': ['机械操作工', '电工', '焊工', '司机', '物流专员'],
  '军人': ['军官', '士官', '特种兵', '军事技术人员', '军事指挥'],
  '其他人员': ['自由职业者', '创业者', '艺术工作者', '体育工作者', '其他']
}

const provinces = [
  '全国',
  '北京',
  '上海',
  '广东',
  '江苏',
  '浙江',
  '山东',
  '四川',
  '湖北',
  '河南',
  '河北'
]

const selectedProvince = ref('全国')
const selectedOccupation = ref('全部')
let barChart: echarts.ECharts | null = null
let lineChart: echarts.ECharts | null = null
let radarChart: echarts.ECharts | null = null
let sankeyChart: echarts.ECharts | null = null


const dataCache = new Map()
const generateData = (base: number, variance: number, cacheKey: string) => {
  if (!dataCache.has(cacheKey)) {
    dataCache.set(cacheKey, Math.floor(base + Math.random() * variance))
  }
  return dataCache.get(cacheKey)
}

const getBarData = () => {
  if (selectedOccupation.value === '全部') {
    return occupations.slice(1).map(occ => ({
      name: occ,
      value: generateData(8000, 12000, `${selectedProvince.value}-${occ}-bar`)
    }))
  }
  const subCats = occupationSubcategories[selectedOccupation.value as keyof typeof occupationSubcategories]
  return subCats.map(sub => ({
    name: sub,
    value: generateData(
      selectedOccupation.value === '企业管理人员' ? 15000 : 8000,
      selectedOccupation.value === '企业管理人员' ? 20000 : 10000,
      `${selectedProvince.value}-${selectedOccupation.value}-${sub}-bar`
    )
  }))
}

const getLineData = () => {
  const years = [2020, 2021, 2022, 2023, 2024]
  const baseSalary = selectedOccupation.value === '企业管理人员' ? 15000 : 8000
  return years.map(year => ({
    year: year,
    value: generateData(baseSalary, 5000, `${selectedProvince.value}-${selectedOccupation.value}-${year}-line`)
  }))
}

const getRadarData = () => {
  const dimensions = ['平均工作时长', '薪资水平', '企业竞争力', '职业晋升率', '行业潜力']
  return dimensions.map(dim => ({
    name: dim,
    value: generateData(60, 40, `${selectedProvince.value}-${selectedOccupation.value}-${dim}-radar`)
  }))
}

const getBarOption = (data: any[]): EChartsOption => ({
  title: {
    text: '查看全国各省各职业平均薪资',
    left: 'center',
    textStyle: { fontSize: 18, fontWeight: 'bold', color: '#333' }
  } as TitleOption,
  tooltip: {
    trigger: 'axis',
    axisPointer: { type: 'shadow' },
    formatter: '{b}: {c}元',
    textStyle: { color: '#333' } 
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '12%',
    top: '15%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: data.map(item => item.name),
    axisLabel: { rotate: 30, interval: 0, fontSize: 12, color: '#333' },
    axisLine: { lineStyle: { color: '#333' } }
  } as XAXisOption,
  yAxis: {
    type: 'value',
    name: '月薪（元）',
    axisLine: { lineStyle: { color: '#333' } },
    splitLine: { lineStyle: { color: '#f0f0f0' } },
    axisLabel: { color: '#333' }
  } as YAXisOption,
  series: [{
    type: 'bar',
    data: data.map(item => ({
      value: item.value,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#6366f1' },
          { offset: 1, color: '#818cf8' }
        ]),
        borderRadius: [4, 4, 0, 0]
      }
    })),
    barWidth: '60%',
    label: { show: true, position: 'top', fontWeight: 'bold', fontSize: 12, color: '#333' }
  }]
})

const getLineOption = (data: any[]): EChartsOption => ({
  title: {
    text: `${selectedOccupation.value}年均薪资变化趋势`,
    left: 'center',
    textStyle: { fontSize: 18, fontWeight: 'bold', color: '#333' }
  } as TitleOption,
  tooltip: { 
    trigger: 'axis', 
    formatter: '{b}年: {c}元',
    textStyle: { color: '#333' }
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '12%',
    top: '15%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: data.map(item => item.year),
    axisLabel: { fontSize: 12, color: '#333' },
    axisLine: { lineStyle: { color: '#333' } }
  } as XAXisOption,
  yAxis: {
    type: 'value',
    name: '年均（元）',
    axisLine: { lineStyle: { color: '#333' } },
    splitLine: { lineStyle: { color: '#f0f0f0' } },
    axisLabel: { color: '#333' }
  } as YAXisOption,
  series: [{
    type: 'line',
    data: data.map(item => item.value),
    symbol: 'circle',
    symbolSize: 8,
    lineStyle: { width: 3, color: '#6366f1' },
    itemStyle: { color: '#6366f1', borderColor: '#fff', borderWidth: 2 },
    smooth: true,
    label: { show: true, position: 'top', fontWeight: 'bold', fontSize: 12, color: '#333' }
  }]
})

const getRadarOption = (data: any[]): EChartsOption => ({
  title: {
    text: `查看${selectedOccupation.value}行业优势`,
    left: 'center',
    textStyle: { fontSize: 18, fontWeight: 'bold', color: '#333' }
  } as TitleOption,
  tooltip: { 
    trigger: 'item',
    textStyle: { color: '#333' }
  },
  radar: {
    indicator: data.map(item => ({ 
      name: item.name, 
      max: 100,
      min: 0  // 显式设置min
    })),
    axisName: {
      color: '#333'
    },
    splitArea: {
      show: false  // 关闭分割区域显示
    },
    axisLine: {
      lineStyle: {
        color: 'rgba(0, 0, 0, 0.1)'
      }
    },
    splitLine: {
      lineStyle: {
        color: 'rgba(0, 0, 0, 0.1)'
      }
    }
  },
  series: [{
    type: 'radar',
    data: [{
      value: data.map(item => item.value),
      name: '能力评估',
      lineStyle: { width: 2, color: '#6366f1' },
      symbol: 'circle',
      symbolSize: 6,
      itemStyle: { color: '#6366f1' },
      label: { 
        show: true, 
        formatter: (params: any) => params.value, 
        fontSize: 12,
        color: '#333'
      }
    }]
  }]
})

// 桑基图数据
const generateSankeyData = () => {
  const majors = ['计算机', '金融', '教育']
  const industries = ['IT', '金融', '教育', '制造业', '自由职业']
  
  // 生成节点列表（确保唯一性）
  const nodes = [
    ...majors.map((m, i) => ({ 
      name: m,
      id: `major_${i}`  // 添加唯一ID
    })),
    ...industries.map((i, j) => ({ 
      name: i,
      id: `industry_${j}`  // 添加唯一ID
    }))
  ]
  // 生成随机链路数据
  const links = [
    { source: 'major_0', target: 'industry_0', value: 4500 },
    { source: 'major_0', target: 'industry_1', value: 800 },
    { source: 'major_1', target: 'industry_1', value: 3800 },
    { source: 'major_1', target: 'industry_0', value: 600 },
    { source: 'major_2', target: 'industry_2', value: 3200 },
    { source: 'major_2', target: 'industry_4', value: 700 },
    { source: 'major_2', target: 'industry_3', value: 300 }
  ].map(link => ({
    ...link,
    value: link.value + Math.floor(Math.random() * 500)
  }))

  return { nodes, links }
}

// 新增桑基图配置
const getSankeyOption = (): EChartsOption => {
  const { nodes, links } = generateSankeyData();

  // 新增：创建 ID 到名称的映射表
  const nodeMap = new Map<string, string>();
  nodes.forEach(node => {
    nodeMap.set(node.id, node.name);
  });

  return {
    title: {
      text: '毕业生专业-行业流向分析',
      left: 'center'
    },
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => {
        if (params.dataType === 'edge') {
          // 通过 ID 映射获取名称
          const sourceName = nodeMap.get(params.data.source) || params.data.source;
          const targetName = nodeMap.get(params.data.target) || params.data.target;
          return `${sourceName} 就业 ${targetName}方向<br/>人数：${params.data.value}`;
        }
        return nodeMap.get(params.data.id) || params.name; // 处理节点名称
      }
    },
    series: [{
      type: 'sankey',
      data: nodes,
      links: links,
      focusNodeAdjacency: true,
      levels: [{
        depth: 0,
        itemStyle: { color: '#6366f1' }
      }, {
        depth: 1,
        itemStyle: { color: '#10b981' }
      }],
      lineStyle: {
        color: 'source',
        curveness: 0.5,
        opacity: 0.6
      },
      label: {
        show: true,         // 关键修复：启用标签显示
        formatter: '{b}',   // 关键修复：绑定 name 字段
        color: '#333',
        fontSize: 12
      },
      nodeWidth: 20,
      nodeGap: 15
    }]
  };
};

const initCharts = () => {
  try {
    barChart = echarts.init(document.getElementById('barChart')!)
    lineChart = echarts.init(document.getElementById('lineChart')!)
    radarChart = echarts.init(document.getElementById('radarChart')!)
    sankeyChart = echarts.init(document.getElementById('sankeyChart')!)
    
    // 确保DOM已挂载
    nextTick(() => {
      updateCharts()
    })
  } catch (error) {
    console.error('图表初始化失败:', error)
  }
}

const updateCharts = () => {
  barChart?.setOption(getBarOption(getBarData()))
  lineChart?.setOption(getLineOption(getLineData()))
  radarChart?.setOption(getRadarOption(getRadarData()))
  sankeyChart?.setOption(getSankeyOption())
}

const handleResize = () => {
  barChart?.resize()
  lineChart?.resize()
  radarChart?.resize()
  sankeyChart?.resize()
}

watch([selectedProvince, selectedOccupation], updateCharts)

// 添加触摸滑动相关逻辑
const containerRef = ref<HTMLElement | null>(null)
const startX = ref(0)
const scrollLeft = ref(0)
const isDragging = ref(false)

const handleTouchStart = (e: TouchEvent) => {
  if (!containerRef.value || window.innerWidth > 768) return
  isDragging.value = true
  startX.value = e.touches[0].pageX - containerRef.value.offsetLeft
  scrollLeft.value = containerRef.value.scrollLeft
}

const handleTouchMove = (e: TouchEvent) => {
  if (!isDragging.value || !containerRef.value || window.innerWidth > 768) return
  e.preventDefault()
  const x = e.touches[0].pageX - containerRef.value.offsetLeft
  const walk = (x - startX.value) * 2 // 调整滑动速度
  containerRef.value.scrollLeft = scrollLeft.value - walk
}

const handleTouchEnd = () => {
  isDragging.value = false
}

// 在onMounted中添加事件监听
onMounted(() => {
  initCharts()
  window.addEventListener('resize', handleResize)
  if (containerRef.value) {
    containerRef.value.addEventListener('touchstart', handleTouchStart, { 
      passive: false 
    })
    containerRef.value.addEventListener('touchmove', handleTouchMove, { 
      passive: false 
    })
    containerRef.value.addEventListener('touchend', handleTouchEnd)
  }
})

// 在onUnmounted中移除事件监听
onUnmounted(() => {
  barChart?.dispose()
  lineChart?.dispose()
  radarChart?.dispose()
  sankeyChart?.dispose()
  window.removeEventListener('resize', handleResize)
  if (containerRef.value) {
    containerRef.value.removeEventListener('touchstart', handleTouchStart)
    containerRef.value.removeEventListener('touchmove', handleTouchMove)
    containerRef.value.removeEventListener('touchend', handleTouchEnd)
  }
})
</script>

<template>
  <div class="mobile-container" ref="containerRef">
    <div class="container">
      <header class="header">
        <h1 class="title">多维职业分析平台</h1>
        <p class="subtitle">基于大数据分析的职业薪资与能力评估系统</p>
      </header>
      
      <div class="controls">
        <div class="filter-card">
          <label class="filter-label">
            <span class="filter-icon">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M21 3H3l9 12 9-12z"/>
                <path d="M12 15L3 3h18l-9 12z"/>
              </svg>
            </span>
            选择地区：
          </label>
          <select v-model="selectedProvince" class="filter-select">
            <option v-for="province in provinces" :key="province" :value="province">
              {{ province }}
            </option>
          </select>
        </div>
        
        <div class="filter-card">
          <label class="filter-label">
            <span class="filter-icon">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
              </svg>
            </span>
            选择职业：
          </label>
          <select v-model="selectedOccupation" class="filter-select">
            <option v-for="occupation in occupations" :key="occupation" :value="occupation">
              {{ occupation }}
            </option>
          </select>
        </div>
      </div>

      <div class="dashboard">
        <div class="main-chart">
          <div class="chart-card">
            <div id="barChart" class="chart"></div>
          </div>
          <!-- 新增桑基图 -->
          <div class="chart-card">
            <div id="sankeyChart" class="chart"></div>
          </div>
        </div>
        
        <div class="secondary-charts">
          <div class="chart-card">
            <div id="radarChart" class="chart"></div>
          </div>
          <div class="chart-card">
            <div id="lineChart" class="chart"></div>
          </div>
        </div>

      </div>
    </div>
  </div>
</template>

<style scoped>
.container {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  background-color: #f8f9ff;
  font-family: 'Inter', sans-serif;
  color: #333;
}

.header {
  text-align: center;
  margin-bottom: 30px;
  padding: 25px 0;
  background: linear-gradient(135deg, #6366f1 0%, #818cf8 100%);
  border-radius: 12px;
  color: white;
}

.title {
  margin: 0;
  font-size: 2rem;
  font-weight: 700;
}

.subtitle {
  margin: 8px 0 0;
  font-size: 0.95rem;
  opacity: 0.9;
}

.controls {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 25px;
  flex-wrap: wrap;
}

.filter-card {
  background: white;
  padding: 12px 16px;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(99, 102, 241, 0.1);
  display: flex;
  align-items: center;
  border: 1px solid rgba(99, 102, 241, 0.1);
}

.filter-label {
  margin-right: 12px;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  color: #333;
}

.filter-icon {
  display: inline-flex;
  margin-right: 8px;
  color: #6366f1;
}

.filter-select {
  padding: 8px 12px;
  border-radius: 6px;
  border: 1px solid #e0e7ff;
  font-size: 14px;
  outline: none;
  background-color: #f9fafb;
  min-width: 180px;
  cursor: pointer;
  color: #333;
}

.dashboard {
  flex: 1;
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
}

.main-chart {
  grid-column: 1;
}

.secondary-charts {
  grid-column: 2;
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 20px;
}

.chart-card {
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.08);
  padding: 16px;
}

.chart {
  width: 100%;
  height: 400px;
}

.main-chart .chart {
  height: 500px;
}

@media (max-width: 992px) {
  .dashboard {
    grid-template-columns: 1fr;
  }
  
  .secondary-charts {
    grid-column: 1;
    grid-template-rows: auto auto;
    grid-template-columns: 1fr 1fr;
  }
  
  .chart {
    height: 350px;
  }
  
  .main-chart .chart {
    height: 400px;
  }
}

@media (max-width: 768px) {
  .controls {
    flex-direction: column;
    align-items: stretch;
    gap: 15px;
  }
  
  .filter-card {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .filter-label {
    margin-bottom: 8px;
  }
  
  .filter-select {
    width: 100%;
  }
  
  .title {
    font-size: 1.6rem;
  }
  
  .subtitle {
    font-size: 0.85rem;
  }
  
  .header {
    padding: 20px 0;
  }
  
  .secondary-charts {
    grid-template-columns: 1fr;
  }
  
  .chart {
    height: 300px;
  }
  
  .main-chart .chart {
    height: 350px;
  }
}
/* 新增移动容器样式 */
.mobile-container {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch; /* 启用iOS平滑滚动 */
  touch-action: pan-y; /* 允许垂直滚动但限制水平滚动 */
}

/* 当屏幕宽度小于768px时启用横向滚动 */
@media (max-width: 768px) {
  .mobile-container {
    overflow-x: scroll;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    height: 100vh;
  }
  
  .container {
    width: 150%;
    min-width: 768px;
    display: block;
  }
  
  /* 禁用图表容器的横向滚动 */
  .chart-card {
    overflow: hidden;
  }
}

.container {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  background-color: #f8f9ff;
  font-family: 'Inter', sans-serif;
  color: #333;
}

/* 桑葚图 */
.main-chart {
  display: grid;
  grid-template-rows: auto auto;
  gap: 20px;
}

#sankeyChart {
  width: 100%;
  height: 500px;
  margin-top: 20px;
  min-height: 400px; /* 防止内容挤压 */
}

@media (max-width: 768px) {
  #sankeyChart {
    height: 350px;
  }
}

/* 新增超小屏幕样式 */
@media (max-width: 480px) {
  .mobile-container {
    overflow-x: scroll;
  }
  
  .container {
    width: 180%;
    min-width: 600px;
  }
  
  .title {
    font-size: 1.4rem;
  }
  
  .subtitle {
    font-size: 0.75rem;
  }
  
  .filter-label {
    font-size: 12px;
  }
  
  .filter-select {
    font-size: 12px;
    padding: 6px 8px;
  }
  
  .chart {
    height: 250px;
  }
  
  .main-chart .chart {
    height: 300px;
  }
  
  /* 调整图表内文字大小 */
  :deep(.echarts) text {
    font-size: 10px !important;
  }
}

/* 横屏模式优化 */
@media screen and (max-width: 992px) and (orientation: landscape) {
  .mobile-container {
    overflow-x: auto;
  }
  
  .container {
    width: 100%;
    min-width: auto;
  }
  
  .dashboard {
    grid-template-columns: 1fr 1fr;
  }
  
  .main-chart {
    grid-column: span 2;
  }
  
  .secondary-charts {
    grid-column: span 2;
    grid-template-columns: 1fr 1fr;
  }
}

</style>